home *** CD-ROM | disk | FTP | other *** search
/ C/C++ Users Group Library 1996 July / C-C++ Users Group Library July 1996.iso / vol_200 / 228_01 / bdsmark.c < prev    next >
Text File  |  1987-07-29  |  6KB  |  233 lines

  1. /*
  2. **    bdsmark.c -- mark library functions that BDS C implements in a
  3. **  nonstandard fashion.
  4. **
  5. **    This program will accept a BDS C program as input and write
  6. **  the program to its output with markers placed around the BDS C
  7. **  standard library functions that are not implemented in a standard
  8. **  manner.  In some cases the differences are trivial.  Other times
  9. **  they are not.  Using this program to mark a file can help in
  10. **  converting a file to portable form for compilation in a system
  11. **  with a standard "standard" library.
  12. **
  13. **    David D. Clark
  14. **    3 February 1987
  15. */
  16.  
  17. #include    "stdio.h"        /* Aztec won't take "<...>" notation */
  18. /*#include    "ctype.h"*/        /* delete for 8 bit versions */
  19.  
  20. #define QC
  21.  
  22. #ifndef    TRUE
  23. #define TRUE    1
  24. #define    FALSE    0
  25. #endif
  26.  
  27. #define    TOKLEN        9        /* max length for token to test */
  28. #define    MARKER        "^^"        /* marker in output file */
  29.  
  30. char    *nonstd[] =            /* nonstandard functions */
  31.     {                /* reason: */
  32.        "creat",            /* parameters */
  33.        "exit",            /* doesn't flush files */
  34.        "fgets",            /* parameters */
  35.        "fopen",            /* parameters */
  36.        "getc",            /* text vs binary i/o */
  37.        "getchar",            /* text vs binary i/o */
  38.        "putc",            /* text vs binary i/o */
  39.        "puts",            /* doesn't append '\n' */
  40.        "read",            /* parameters */
  41.        "tolower",            /* checks argument range */
  42.        "toupper",            /* checks argument range */
  43.        "write"            /* parameters */
  44.     };
  45.  
  46. char    c;                /* current scanner character */
  47. char    token[TOKLEN];            /* token to be tested */
  48. FILE    *infile, *outfile;        /* input and output files */
  49. FILE    *fopen();
  50.  
  51.  
  52. main(argc, argv)
  53. int    argc;
  54. char    *argv[];
  55. {
  56.  
  57.     if (argc != 3)
  58.     {
  59.         fputs("Usage: bdsmark infile outfile\n", stderr);
  60.         exit(1);
  61.     }
  62.     
  63.     if ((infile = fopen(*++argv, "r")) == NULL)
  64.     {
  65.         fputs("Can't open input file:  ", stderr);
  66.         fputs(*argv, stderr);
  67.         putc('\n', stderr);
  68.         exit(1);
  69.     }
  70.  
  71.     if ((outfile = fopen(*++argv, "w")) == NULL)
  72.     {
  73.         fputs("Can't open output file:  ", stderr);
  74.         fputs(*argv, stderr);
  75.         putc('\n', stderr);
  76.         exit(1);
  77.     }
  78.  
  79.     scanner();            /* do the translation */
  80.  
  81.     fclose(infile);
  82.     fclose(outfile);
  83.     exit(0);
  84. }
  85.  
  86.  
  87. /*
  88. **    scanner -- scan the input file and produce the marked
  89. **  output file.  This function looks specifically for comments,
  90. **  string constants, character constants and identifiers.  When
  91. **  a potential comment is detected, control is passed to the
  92. **  function "commenter" to pass the rest of the comment without
  93. **  change.  String and character constants are also passed unchanged.
  94. **  When an identifier is detected, it is copied into the global
  95. **  character array "token", then "tsttoken" is called to compare
  96. **  it to the names of the nonstandard functions.  If a match is
  97. **  found, it is marked in the output file.
  98. */
  99.  
  100. scanner()
  101. {
  102. static char *cp;
  103. static int i;
  104.  
  105.     while ((c = getc(infile)) && !feof(infile) && !ferror(infile))
  106.     {
  107.         if (c == '/')            /* check for a comment */
  108.             commenter();
  109.         else if (c == '\'')        /* handle character constant */
  110.             passuntil('\'');
  111.         else if (c == '"')        /* handle literal string */
  112.             passuntil('"');
  113.         else if (iscsymf(c))        /* look for an identifier */
  114.         {
  115.             i = 0;
  116.             cp = token;
  117.             while (iscsym(c) && (i < (TOKLEN - 1)))
  118.             {
  119.                 *cp++ = c;
  120.                 i++;
  121.                 c = getc(infile);
  122.             }
  123.             *cp = 0;
  124.             if (tsttoken())        /* mark it */
  125.             {
  126.                 fputs(MARKER, outfile);
  127.                 fputs(token, outfile);
  128.                 fputs(MARKER, outfile);
  129.             }
  130.             else
  131.                 fputs(token, outfile);
  132.         }
  133.         putc(c, outfile);    /* write last char scanned */
  134.     }
  135.     putc(c, outfile);        /* try to write end-of-file char */
  136. }
  137.  
  138.  
  139. /*
  140. **    passuntil -- pass characters from "infile" to "outfile" until
  141. **  the terminator character "term" is detected.  Detect and pass
  142. **  "escaped" character sequences unchanged.  On entry, the scanner
  143. **  character in "c" has not yet been written to the output file.  On
  144. **  return, the scanner character will contain the terminator character
  145. **  ready for output.
  146. */
  147.  
  148. passuntil(term)
  149. int term;
  150. {
  151.     putc(c, outfile);
  152.     while ((c = getc(infile)) != term)
  153.     {
  154.         putc(c, outfile);
  155.         if (c == '\\')
  156.         {
  157.             c = getc(infile);
  158.             putc(c, outfile);
  159.         }
  160.     }
  161. }
  162.  
  163.  
  164. /*
  165. **    tsttoken -- return TRUE if the token matches one of the
  166. **  names of the nonstandard functions in the variable "nonstd", FALSE
  167. **  otherwise.  Because there are only a few, a simple linear search
  168. **  is done on the array. 
  169. */
  170.  
  171. int tsttoken()
  172. {
  173. static char **t;
  174.  
  175.     for (t = nonstd; **t; t++)
  176.     {
  177.         if (strcmp(*t, token) == 0)
  178.             return (TRUE);
  179.     }
  180.     return (FALSE);
  181. }
  182.  
  183.  
  184. /*
  185. **    commenter -- pass comments unchanged.  On entry, the leading
  186. **  '/' has already been detected.  On return, c contains the final '/'
  187. **  of the comment.
  188. **
  189. **    This function expects comments to be in the UNIX style.  It
  190. **  does not handle nested comments correctly.  In any case, the
  191. **  damage caused by nested comments should be minimal.  The worst
  192. **  that should occur is marking of nonstandard function names that
  193. **  appear in the comment.
  194. */
  195.  
  196. commenter()
  197. {
  198.  
  199.     putc(c, outfile);        /* write the '/' char */
  200.     if ((c = getc(infile)) == '*')    /* is next char '*'? */
  201.     {                /* yes, handle rest of comment */
  202.         putc(c, outfile);
  203.         c = getc(infile);
  204.         for (;;)
  205.         {
  206.             putc(c, outfile);
  207.             if (c == '*')    /* '*' of end of comment? */
  208.             {
  209.                 if ((c = getc(infile)) == '/')
  210.                     return;    /* got it all */
  211.                 else
  212.                     putc(c, outfile);
  213.             }
  214.             c = getc(infile);
  215.         }
  216.     }
  217. }
  218.  
  219.  
  220. #ifndef QC
  221.  
  222.  
  223. /*
  224. **    iscsymf -- is c a valid character for the first character in
  225. **  a C symbol?
  226. */
  227.  
  228. int iscsymf(c)
  229. int c;
  230. {
  231.     return (isalpha(c) || c == '_');
  232. }
  233.